import { componentTypeToConfig } from "./base-components";
import {
  DraggableTreeNode,
  FormConfig,
  FormDataType,
  FormType,
  IDMapType,
  Options,
  RootObject,
  Rule,
  TypeItem,
} from "./type.d";
import { DateItemAttr } from "./components/display/date/display-date";
import { RadioItemAttr } from "./components/display/radio/display-radio";
import { SelectItemAttr } from "./components/display/select/display-select";
import { InputItemAttr } from "./components/display/input/display-input";
import { TitleItemAttr } from "./components/display/title/display-title";

// VueDraggable 拖拽 group设定
export const DraggableGroup = "Component";

export const types: TypeItem[] = [
  { label: "标题", value: FormType.FORM_TYPE_TITLE },
  { label: "日期时间", value: FormType.FORM_TYPE_DATE },
  { label: "单选框", value: FormType.FORM_TYPE_RADIO },
  { label: "下拉框", value: FormType.FORM_TYPE_SELECT },
  { label: "输入框", value: FormType.FORM_TYPE_INPUT },
];
// select组件options类型
export const selectType = {
  DICT: "dict",
  DIY: "diy",
};
export const creatUuid = function () {
  return (
    new Date().getTime().toString(36) + Math.random().toString(36).substr(2, 9)
  );
};

// 五种控件的基本设置
export const ItemAttrs: RootObject = {
  // 日期时间
  [FormType.FORM_TYPE_DATE]: DateItemAttr,
  // 单选框
  [FormType.FORM_TYPE_RADIO]: RadioItemAttr,
  // 下拉框
  [FormType.FORM_TYPE_SELECT]: SelectItemAttr,
  // 输入框
  [FormType.FORM_TYPE_INPUT]: InputItemAttr,
  // 标题
  [FormType.FORM_TYPE_TITLE]: TitleItemAttr,
};
// 根据类型，返回控件基本设置
export function getItemAttr(type: FormType) {
  return ItemAttrs[type as keyof RootObject];
}

// 新增数据项
export function addDataItem(
  label: string,
  componentType: FormType
): DraggableTreeNode {
  let row = false;
  switch (componentType) {
    case FormType.FORM_TYPE_TITLE:
      row = true;
      break;
    default:
      row = false;
      break;
  }
  return {
    // 唯一ID，用于绑定值
    id: creatUuid(),
    // 模块名
    label,

    // 独占一行
    row: row,
    // 组件类型
    componentType,
    // 组件信息
    component: getItemAttr(componentType),
    // 配置组件类型
    componentConfigType: componentTypeToConfig(componentType),
  };
}
export const formDataDisplay = {
  a: "2024-05-07",
  b: 0,
  c: 0,
  d: "输入测试",
  e: [{ hosMedicalPayMethod: 222 }],
};

export const componentList = [
  addDataItem("标题", FormType.FORM_TYPE_TITLE),
  addDataItem("日期", FormType.FORM_TYPE_DATE),
  addDataItem("单选", FormType.FORM_TYPE_RADIO),
  addDataItem("下拉", FormType.FORM_TYPE_SELECT),
  addDataItem("输入", FormType.FORM_TYPE_INPUT),
];
export function deepClone(obj: any, hash = new WeakMap()) {
  if (obj === null) return obj; // 如果是null或者undefined我就不进行拷贝操作
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof RegExp) return new RegExp(obj);
  // 可能是对象或者普通的值  如果是函数的话是不需要深拷贝
  if (typeof obj !== "object") return obj;
  // 是对象的话就要进行深拷贝
  if (hash.get(obj)) return hash.get(obj);
  let cloneObj = new obj.constructor();
  // 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身
  hash.set(obj, cloneObj);
  for (let key in obj) {
    // eslint-disable-next-line no-prototype-builtins
    if (obj.hasOwnProperty(key)) {
      // 实现一个递归拷贝
      if (key === "id") {
        cloneObj[key] = creatUuid();
      } else {
        cloneObj[key] = deepClone(obj[key], hash);
      }
    }
  }
  return cloneObj;
}

// 当前表单的默认配置
export function createFormConfig(
  schemas: DraggableTreeNode[] = []
): FormConfig {
  return {
    // 表单数据对象
    // model: {},
    // 表单验证规则
    // 行内表单模式
    inline: true,
    // 表单域标签的位置 right/left/top，固定right
    "label-position": "right",
    // label-width 表单域标签的宽度，例如 '50px'
    "label-width": "auto",
    // 用于控制该表单内组件的尺寸 medium / small / mini
    size: "small",
    // 表单配置，schemas里面装每一个控件属性
    schemas,
    // 当前选中的控件
    currentItem: null,
    // currentItem: {
    //   component: "",
    //   componentProps: {}
    // },
    // activeKey: 1
  };
}
export const formConfig = createFormConfig([]);

// 根据hiddenRules、FormData、IDMap返回布尔值，返回true表示隐藏，返回false表示不隐藏
export function getHidden(
  hiddenRules: Rule[],
  formData: FormDataType,
  IDMap: IDMapType
): boolean {
  if (!hiddenRules.length) {
    return false;
  }
  if (!Object.keys(formData).length) {
    return false;
  }
  let evalStr = "";
  // fieldId：对应的控件id；operator：操作符；value：填写的值；connect：连接词
  hiddenRules.forEach(({ fieldId, operator, value, connect }) => {
    let componentValue = formData[IDMap[fieldId]],
      isNumber = !isNaN(Number(componentValue));
    // 让数字和数字比较，字符和字符比较
    if (isNumber) {
      componentValue = Number(componentValue);
      value = Number(value);
    } else {
      componentValue = `'${componentValue}'`;
      value = `'${value}'`;
    }
    evalStr += `${componentValue} ${operator} ${value} ${
      connect ? connect : ""
    }`;
  });
  console.log(evalStr, "evalStr");
  return eval(evalStr);
}

export const selectTypeOptions = [
  { label: "字典值", value: selectType.DICT },
  { label: "自定义", value: selectType.DIY },
];

// 必填、非必填字典值
export const requiredOptions = [
  { label: "必填", value: true },
  { label: "非必填", value: false },
];

// 表格列填充控件类型 字典值
export const elTableColumnTypeOptions = [
  { label: "日期时间", value: "datetime" },
  { label: "输入框", value: "input" },
];
// 新增table列
export function addColumn() {
  return {
    required: false,
    "el-table-column_label": "新建列名称",
    "el-table-column_type": "input", // input或者是datetime，默认是input
    "el-table-column_tableName": "", // 通过数据来源选择的表名
    "el-table-column_prop": "", // 通过数据来源选择的字段
    className: creatUuid(), // 需要动态变化这个值来触发el-table-column更新
  };
}
// 树筛选语法：依据节点中的label值筛选
export function treeFilter(
  nodes: DraggableTreeNode[],
  search: string
): DraggableTreeNode[] {
  const result = [];
  for (let i = 0; i < nodes.length; i++) {
    if (nodes[i].label.indexOf(search) !== -1) {
      result.push(nodes[i]);
    }
  }
  return result;
}
// 校验表格表头列设置是否合理
export function tableOptionsVerify(options: Options[] = []) {
  if (!options.length) {
    return false;
  }
  for (let index = 0; index < options.length; index++) {
    const item = options[index];
    if (
      item["el-table-column_label"] &&
      item["el-table-column_tableName"] &&
      item["el-table-column_prop"]
    ) {
      continue;
    } else {
      return false;
    }
  }
  // 返回true表示合理
  return true;
}
